package com.chucang.shucang.common.base.utils;

import lombok.experimental.UtilityClass;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @author flitsneak
 * @email flitsneak@gmail.com
 * @date 2022/9/12 22:44
 * @description 邀请码，用户名生产工具
 */
@UtilityClass
public class DecToSfUtil {
    private final char[] inviteArray = {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '8', '5', '2', '7', '3', '6', '4', '0', '9', '1', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '+', '-'};

    private final char[] nameArray = {'0', '9', '1', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '+', '-', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '8', '5', '2', '7', '3', '6', '4'};

    /**
     * 转换为64进制
     *
     * @param number 十进制
     * @return 64 进制
     */
    public String toInviteSf(long number) {
        return getSfStr(number, inviteArray);
    }

    /**
     * 转换为64进制
     *
     * @param number 十进制
     * @return 64 进制
     */
    public String toNameSf(long number) {
        return getSfStr(number, nameArray);
    }

    private String getSfStr(long number, char[] array) {
        // 创建栈
        Deque<Character> stack = new ArrayDeque<>();
        StringBuilder result = new StringBuilder(0);
        while (number >= 1) {
            // 进栈
            stack.push(array[(int) (number % 64)]);
            number = number / 64;
        }
        while (!stack.isEmpty()) {
            // 出栈
            result.append(stack.pop());
        }
        return result.toString();
    }

    /**
     * 转十进制
     *
     * @param str 64进制数
     * @return 十进制
     */
    public long toInviteDec(String str) {
        // 倍数
        long multiple = 1;
        long result = 0;
        char c;
        for (int i = 0; i < str.length(); i++) {
            c = str.charAt(str.length() - i - 1);
            result += decodeInviteChar(c) * multiple;
            multiple = multiple * 64;
        }
        return result;
    }

    private long decodeInviteChar(Character c) {
        for (int i = 0; i < inviteArray.length; i++) {
            if (c == inviteArray[i]) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 转十进制
     *
     * @param str 64进制数
     * @return 十进制
     */
    public long toNameDec(String str) {
        // 倍数
        long multiple = 1;
        long result = 0;
        char c;
        for (int i = 0; i < str.length(); i++) {
            c = str.charAt(str.length() - i - 1);
            result += decodeNameChar(c) * multiple;
            multiple = multiple * 64;
        }
        return result;
    }

    private long decodeNameChar(Character c) {
        for (int i = 0; i < nameArray.length; i++) {
            if (c == nameArray[i]) {
                return i;
            }
        }
        return -1;
    }
}
